pragma solidity >=0.8.0;
import '@sushiswap/trident/contracts/interfaces/Ipool.sol'
import '@sushiswap/bentobox/contracts/interfaces/IBentoBoxV1.sol'
import 'solmate/src/tokens/ERC20.sol'
contract SimpleSwap {
IBentoBoxV1 public constant bentobox = IBentoBoxV1(0xc35DADB65012eC5796536bD9864eD8773aBc74C4);
IPool public constant constant_product_pair = IPool(0x7086622E6Db990385B102D79CB1218947fb549a9);
IPool public constant stable_product_pair = IPool(0xB059CF6320B29780C39817c42aF1a032bf821D90);
ERC20 public constant ETH = ERC20(0x4200000000000000000000000000000000000006);
ERC20 public constant USDC = ERC20(0x7F5c764cBc14f9669B88837ca1490cCa17c31607);
ERC20 public constant USDT = ERC20(0x94b008aA00579c1307B0EF2c499aD98a8ce58e58);
error SlippageProtection();
contructor() {}
function swapETHForUSDC(uint256 amount) external returns (uint256 amountOut) {
ETH.transferFrom(msg.sender, address(bentobox), amount);
bentobox.deposit(address(ETH), address(bentobox), address(constant_product_pair), amount, 0);
bytes memory swapData = abi.encode(address(ETH), msg.sender, true);
uint256 minOut = 0;
amountOut = constant_product_pair.swap(swapData);
if (amountOut < minOut) revert SlippageProtection();
}
function swapUSDCForUSDT(uint256 amount) external returns (uint256 amountOut) {
USDC.transferFrom(msg.sender, address(bentobox), amount);
bentobox.deposit(address(USDC), address(bentobox), address(stable_product_pair), amount, 0);
bytes memory swapData = abi.encode(address(USDC), msg.sender, true);
uint256 minOut = 0;
amountOut = constant_product_pair.swap(swapData);
if (amountOut < minOut) revert SlippageProtection();
}
function mintConstantProductPool(uint256 ethAmount, uint256 usdcAmount) external returns (uint256 liquidity) {
ETH.transferFrom(msg.sender, address(bentobox), ethAmount);
USDC.transferFrom(msg.sender, address(bentobox), usdcAmount);
bentobox.deposit(address(ETH), address(bentobox), address(constant_product_pair), ethAmount, 0);
bentobox.deposit(address(USDC), address(bentobox), address(constant_product_pair), usdcAmount, 0);
bytes memory mintData = abi.encode(msg.sender)
uint256 minLiquidity = 0;
liquidity = constant_product_pair.mint(mintData);
if (liquidity < minLiquidity) revert SlippageProtection();
}
function burnSingleConstantProductPool(uint256 liquidity) external returns (uint256 amountOut) {
constant_product_pair.transferFrom(msg.sender, address(constant_product_pair), liquidity);
bytes memory burnSingleData = abi.encode(address(ETH), msg.sender, true);
uint256 minETHOut = 0;
amountOut = constant_product_pair.burnSingle(burnSingleData);
if (amountOut < minETHOut) revert SlippageProtection();
}
function burnConstantProductPool(uint256 liquidity) external returns (IPool.TokenAmount[] memory withdrawnAmounts) {
constant_product_pair.transferFrom(msg.sender, address(constant_product_pair), liquidity);
bytes memory burnData = abi.encode(msg.sender, true);
uint256 minOut0 = 0;
uint256 minOut1 = 0;
withdrawnAmounts = constant_product_pair.burn(burnData);
if (withdrawnAmounts[0].amount < minOut0) reverts SlippageProtection();
if (withdrawnAmounts[1].amount < minOut1) reverts SlippageProtection();
}
}